/*
 * imgBox - jQuery Plugin
 * Yet another lightbox alternative
 *
 * Copyright (c) 2009 jQueryGlobe
 * Examples and documentation at: http://jqueryglobe.com/article/imgbox/
 * 
 * Version: 1.0.0 (21/10/2009)
 * Requires: jQuery v1.3+
 * 
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */

;
(function($) {
    $.fn.fixPNG = function() {
        return this.each(function () {
            var image = $(this).css('backgroundImage');

            if (image.match(/^url\(["']?(.*\.png)["']?\)$/i)) {
                image = RegExp.$1;
                $(this).css({
                    'backgroundImage': 'none',
                    'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=" + ($(this).css('backgroundRepeat') == 'no-repeat' ? 'crop' : 'scale') + ", src='" + image + "')"
                }).each(function () {
                    var position = $(this).css('position');
                    if (position != 'absolute' && position != 'relative')
                        $(this).css('position', 'relative');
                });
            }
        });
    };

    var elem, opts, preloader, orig_pos, final_pos, busy = false, nr, zindex = 90, titleh = 0, shadow = 20, margin = 20, fx = $.extend($('<div/>')[0], {
        prop: 0
    });

    $.fn.imgbox = function(settings) {
        return this.unbind('mouseover.pb').bind('mouseover.pb', function() {
            $.imgbox( $(this), settings );
            return false;
        });
    };

    $.imgbox = function(e, o) {
        if (busy) {
            return false;
        }

        elem	= e;
        opts	= $.extend({}, $.fn.imgbox.defaults, o);
        nr		= jQuery.data(elem[0]);

        if ($('#imgbox-wrap-' + nr).length) {
            zoomOut();
            return false;
        }

        hideActivity();

        if (opts.overlayShow) {
            $('#imgbox-overlay')
            .unbind().stop().hide()
            .css({
                'height'	: $(document).height(),
                'opacity'	: opts.overlayOpacity
            })
            .show();
        }

        preloader = new Image;
        preloader.src = $(elem).attr('href');

        if (preloader.complete == false) {
            showActivity();

            $(preloader).unbind().one('load', function() {
                hideActivity();
                zoomIn();
            });

        } else {
            zoomIn();
        }
    };

    $.fn.imgbox.defaults = {
        padding				:	10,
        alignment			:	'auto', // auto OR center
        allowMultiple		:	true,
        autoScale			:	true,
        speedIn				:	500,
        speedOut			:	500,
        easingIn			:	'swing',
        easingOut			:	'swing',
        zoomOpacity			:	false,
        overlayShow			:	false,
        overlayOpacity		:	0.5,
        hideOnOverlayClick	:	true,
        hideOnContentClick	:	true
    };

    function zoomIn() {
        busy = true;

        if (opts.allowMultiple == false) {
            $('.imgbox-wrap').remove();
            $('.imgbox-bg-wrap').remove();

        } else {
            zindex = zindex + 2;
        }

        final_pos = getZoomTo();

        var title = $(elem).attr('title') || '';

        $('<div id="imgbox-wrap-' + nr + '" class="imgbox-wrap"></div>')
        .css({
            'z-index'	:	zindex,
            'padding'	:	opts.padding
        })
        .append('<img class="imgbox-img" id="imgbox-img-' + nr + '" src="' + preloader.src + '" alt="' + title + '" />')
        .appendTo('body');

        $('<div id="imgbox-bg-' + nr + '" class="imgbox-bg-wrap"><div class="imgbox-bg imgbox-bg-n"/><div class="imgbox-bg imgbox-bg-ne"/><div class="imgbox-bg imgbox-bg-e"/><div class="imgbox-bg imgbox-bg-se"/><div class="imgbox-bg imgbox-bg-s"/><div class="imgbox-bg imgbox-bg-sw"/><div class="imgbox-bg imgbox-bg-w"/><div class="imgbox-bg imgbox-bg-nw"/></div>').appendTo('body');

        if ($.browser.msie && parseInt($.browser.version.substr(0, 1)) < 7) {
            $('#imgbox-bg-' + nr).find('.imgbox-bg').fixPNG();
        }

        titleh = 0;

        if (title.length > 0) {
            $('<div id="imgbox-tmp" class="imgbox-title" />').html(title).css('width', final_pos.width).appendTo('body');

            titleh = $('#imgbox-tmp').outerHeight();

            final_pos.height	+= titleh;
            final_pos.top		-= titleh > margin + shadow ? margin : margin * 0.5;

            $('#imgbox-tmp').remove();
            $('#imgbox-wrap-' + nr).append('<div class="imgbox-title">' + title + '</div>');
        }

        if (opts.speedIn > 0) {
            var pos	= getThumbPos();

            orig_pos = {
                top		:	pos.top		- opts.padding,
                left	:	pos.left	- opts.padding,
                width	:	pos.width,
                height	:	pos.height
            };

            $('#imgbox-wrap-' + nr).css(orig_pos).show();
            $('#imgbox-bg-' + nr).css({
                top			: orig_pos.top,
                left		: orig_pos.left,
                width		: orig_pos.width	+ (opts.padding * 2),
                height		: orig_pos.height	+ (opts.padding * 2),
                'z-index'	: zindex - 1
            }).show();

            if (opts.zoomOpacity) {
                final_pos.opacity = 1;
            }

            fx.prop = 0;

            $(fx).animate({
                prop: 1
            }, {
                duration	: opts.speedIn,
                easing		: opts.easingIn,
                step		: draw,
                complete	: _finish
            });

        } else {
            $('#imgbox-img-' + nr ).css('height', (final_pos.height - titleh) + 'px');
            $('#imgbox-wrap-' + nr).css(final_pos).fadeIn('normal',  _finish );
	
            $('#imgbox-bg-' + nr).css({
                top			: final_pos.top,
                left		: final_pos.left,
                width		: final_pos.width	+ (opts.padding * 2),
                height		: final_pos.height	+ (opts.padding * 2),
                'z-index'	: zindex - 1
            }).fadeIn('normal');
        }
    };

    function draw(pos) {
        var width	= Math.round(orig_pos.width		+ (final_pos.width	- orig_pos.width)	* pos);
        var height	= Math.round(orig_pos.height	+ (final_pos.height	- orig_pos.height)	* pos);

        var top		= Math.round(orig_pos.top	+ (final_pos.top	- orig_pos.top)		* pos);
        var left	= Math.round(orig_pos.left	+ (final_pos.left	- orig_pos.left)	* pos);

        $('#imgbox-wrap-' + nr).css({
            'width'		: width		+ 'px',
            'height'	: height	+ 'px',
            'top'		: top		+ 'px',
            'left'		: left		+ 'px'
        });

        $('#imgbox-bg-' + nr).css({
            'width'		: Math.round(width	+ opts.padding * 2 ) + 'px',
            'height'	: Math.round(height	+ opts.padding * 2 ) + 'px',
            'top'		: top	+ 'px',
            'left'		: left	+ 'px'
        });

        $('#imgbox-img-' + nr ).css('height',  Math.round( height - ( ( ((height - Math.min(orig_pos.height, final_pos.height)) * 100) / (Math.max(orig_pos.height - final_pos.height, final_pos.height - orig_pos.height) ) * titleh / 100))) + 'px');

        if (typeof final_pos.opacity !== 'undefined') {
            var opacity = pos < 0.3 ? 0.3 : pos;

            $('#imgbox-wrap-' + nr).css('opacity', opacity);

            if ($.browser.msie == false) {
                $('#imgbox-bg-' + nr).css('opacity', opacity);
            }
        }
    };

    function _finish() {
        if (opts.overlayShow && opts.hideOnOverlayClick) {
            $('#imgbox-overlay').bind('mouseout', {
                elem: elem, 
                nr : nr, 
                opts : opts, 
                titleh : titleh
            }, clickHandler);
        }

        $('#imgbox-wrap-' + nr)
        .css('filter', '')
        .bind('mouseout', {
            elem: elem, 
            nr : nr, 
            opts : opts, 
            titleh : titleh
        }, clickHandler)
        .append('<a href="javascript:;" class="imgbox-close"></a>')
        .children('.imgbox-title')
        .show();

        if ($.browser.msie && parseInt($.browser.version.substr(0, 1)) < 7) {
            $('#imgbox-wrap-' + nr).find('.imgbox-close').fixPNG();
        }

        busy = false;
    };

    function clickHandler(e) {
        e.stopPropagation();

        if (e.target.className == 'imgbox-close' || (e.data.opts.hideOnOverlayClick && e.target.id == 'imgbox-overlay') || (e.data.opts.hideOnContentClick && e.target.className == 'imgbox-img' && ($(this).css('z-index') == zindex || $('.imgbox-img').length == 1))) {
            elem	= e.data.elem;
            nr		= e.data.nr;
            opts	= e.data.opts;
            titleh	= e.data.titleh;
            zoomOut();

        } else if ($(this).css('z-index') < zindex) {
            $(this).next('.imgbox-bg-wrap').css('z-index', ++zindex);
            $(this).css('z-index', ++zindex);
        }
    };

    function zoomOut() {
        if (busy) {
            return false;
        }

        busy = true;

        $('#imgbox-wrap-' + nr)
        .children('.imgbox-close, .imgbox-title')
        .remove();

        if (opts.speedOut > 0) {
            var pos	= getThumbPos();

            orig_pos = {
                top		:	pos.top		- opts.padding,
                left	:	pos.left	- opts.padding,
                width	:	pos.width,
                height	:	pos.height
            };

            var pos = $('#imgbox-wrap-' + nr).position();

            final_pos = {
                top		:	pos.top ,
                left	:	pos.left,
                width	:	$('#imgbox-wrap-' + nr).width(),
                height	:	$('#imgbox-wrap-' + nr).height()
            };

            if (opts.zoomOpacity) {
                final_pos.opacity = 0;
            }

            setTimeout(function() {
                $('#imgbox-wrap-' + nr).css('z-index', 90);
                $('#imgbox-bg-' + nr).css('z-index', 90);
            }, opts.speedOut * 0.5);

            fx.prop = 1;

            $(fx).animate({
                prop: 0
            }, {
                duration	: opts.speedIn,
                easing		: opts.easingIn,
                step		: draw,
                complete	: _clean_up
            });

        } else {

            if (opts.overlayShow) {
                _clean_up();

            } else {
                $('#imgbox-bg-' + nr).fadeOut('fast');
                $('#imgbox-wrap-' + nr).fadeOut('fast', _clean_up );
            }
        }
    };

    function _clean_up() {
        $('#imgbox-bg-' + nr).stop().remove();
        $('#imgbox-wrap-' + nr).remove();

        zindex = zindex > 90 ? zindex - 2 : 90;

        if (opts.overlayShow) {
            $('#imgbox-overlay').unbind().stop().fadeOut(200);
        }

        busy = false;	
    };

    function getZoomTo() {
        var wiew	= getViewport();
        var to		= {
            width : preloader.width, 
            height : preloader.height
            };

        var horizontal_space	= (opts.padding + shadow + margin ) * 2;
        var vertical_space		= (opts.padding + shadow + margin ) * 2;

        if (opts.autoScale && (to.width > (wiew[0] - horizontal_space) || to.height > (wiew[1] - vertical_space))) {
            var ratio = Math.min(Math.min( wiew[0] - horizontal_space, to.width) / to.width, Math.min( wiew[1] - vertical_space, to.height) / to.height);

            to.width	= Math.round(ratio * to.width);
            to.height	= Math.round(ratio * to.height);
        }

        if (opts.alignment == 'center') {
            to.top	= wiew[3] + ((wiew[1] - to.height - opts.padding * 2) * 0.5);
            to.left	= wiew[2] + ((wiew[0] - to.width  - opts.padding * 2) * 0.5);

        } else {
            var pos	= getThumbPos();

            to.top	= pos.top  - ( ( to.height - pos.height  ) * 0.5) - opts.padding ;
            to.left	= pos.left - ( ( to.width  - pos.width   ) * 0.5) - opts.padding ;

            to.top	= to.top 	> wiew[3] + margin + shadow ? to.top	:  wiew[3] + margin + shadow; 
            to.left	= to.left 	> wiew[2] + margin + shadow ? to.left	:  wiew[2] + margin + shadow;

            to.top	= to.top	> wiew[1] + wiew[3] - ( to.height	+ vertical_space )	? wiew[1] + wiew[3] - ( to.height	+ ( margin	+ shadow + opts.padding * 2 ) ) : to.top;
            to.left	= to.left	> wiew[0] + wiew[2] - ( to.width	+ horizontal_space )	? wiew[0] + wiew[2] - ( to.width	+ ( margin  + shadow + opts.padding * 2 ) ) : to.left;
        }

        if ( opts.autoScale == false ) {
            to.top	= to.top 	> wiew[3] + shadow + margin ? to.top	:  wiew[3] + shadow + margin;
            to.left	= to.left 	> wiew[2] + shadow + margin ? to.left	:  wiew[2] + shadow + margin;
        }

        to.top 	= parseInt(to.top);
        to.left	= parseInt(to.left);

        return to;
    };

    function getViewport() {
        return [ $(window).width(), $(window).height(), $(document).scrollLeft(), $(document).scrollTop() ];
    };

    function getThumbPos() {
        var thumb	= $(elem).find('img').eq(0);
        var pos		= thumb.offset();

        pos.top		+= parseFloat( thumb.css('paddingTop') );
        pos.left	+= parseFloat( thumb.css('paddingLeft') );

        pos.top		+= parseFloat( thumb.css('border-top-width') );
        pos.left	+= parseFloat( thumb.css('border-left-width') );

        pos.width	= thumb.width();
        pos.height	= thumb.height();

        return pos;
    };

    function showActivity() {
        var pos	= getThumbPos( elem );

        $('#imgbox-loading').css(pos).show();
    };

    function hideActivity() {
        $(preloader).unbind();
        $('#imgbox-loading').hide();
    };

    function cancelLoading() {
        hideActivity();

        if (opts.overlayShow) {
            $('#imgbox-overlay').unbind().stop().fadeOut(200);
        }
    };

    function init() {
        $('<div id="imgbox-loading"><div></div></div><div id="imgbox-overlay"></div>').appendTo('body');

        $('#imgbox-loading')
        .click(cancelLoading)
        .find('div')
        .css('opacity', 0.4);
    };

    $(document).ready(function() {
        init();
    });

})(jQuery);